import { ApiService, GitCommit } from './ApiService';

/**
 * Git数据服务
 * 通过后端API获取Git相关数据
 */
export class GitService {
  /**
   * 安全创建日期对象
   */
  private static safeCreateDate(dateInput: string | Date): Date {
    if (!dateInput) {
      return new Date();
    }
    
    if (dateInput instanceof Date) {
      return isNaN(dateInput.getTime()) ? new Date() : dateInput;
    }
    
    const date = new Date(dateInput);
    return isNaN(date.getTime()) ? new Date() : date;
  }

  /**
   * 验证日期是否有效
   */
  private static isValidDate(date: Date): boolean {
    return date instanceof Date && !isNaN(date.getTime());
  }
  /**
   * 获取Git提交记录
   */
  static async getCommits(
    projectPath: string,
    options: {
      since?: string;
      until?: string;
      author?: string;
      limit?: number;
      offset?: number;
      includeDiff?: boolean;
    } = {}
  ): Promise<{ success: boolean; data?: GitCommit[]; error?: string }> {
    try {
      const apiResult = await ApiService.git.getCommits(projectPath, {
        since: options.since,
        until: options.until,
        author: options.author,
        maxCount: options.limit,
        includeDiff: options.includeDiff
      });
      return {
        success: apiResult.success,
        data: apiResult.data,
        error: apiResult.error
      };
    } catch (error) {
      return {
        success: false,
        error: `获取Git提交记录失败: ${error instanceof Error ? error.message : '未知错误'}`
      };
    }
  }

  /**
   * 获取指定日期范围的提交记录
   */
  static async getCommitsByDateRange(
    projectPath: string,
    startDate: string,
    endDate: string,
    author?: string,
    includeDiff?: boolean
  ): Promise<{ success: boolean; data?: GitCommit[]; error?: string }> {
    return this.getCommits(projectPath, {
      since: startDate,
      until: endDate,
      author,
      includeDiff
    });
  }

  /**
   * 根据提交哈希获取特定的提交记录
   */
  static async getCommitsByHashes(
    projectPath: string,
    hashes: string[],
    includeDiff?: boolean
  ): Promise<{ success: boolean; data?: GitCommit[]; error?: string }> {
    try {
      const apiResult = await ApiService.git.getCommitsByHashes(projectPath, hashes, includeDiff);
      return {
        success: apiResult.success,
        data: apiResult.data,
        error: apiResult.error
      };
    } catch (error) {
      return {
        success: false,
        error: `根据哈希获取提交记录失败: ${error instanceof Error ? error.message : '未知错误'}`
      };
    }
  }

  /**
   * 获取今日提交记录
   */
  static async getTodayCommits(
    projectPath: string,
    author?: string,
    includeDiff?: boolean
  ): Promise<{ success: boolean; data?: GitCommit[]; error?: string }> {
    const today = new Date();
    const startOfDay = new Date(today.getFullYear(), today.getMonth(), today.getDate());
    const endOfDay = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 23, 59, 59);
    
    return this.getCommitsByDateRange(
      projectPath,
      startOfDay.toISOString(),
      endOfDay.toISOString(),
      author,
      includeDiff
    );
  }

  /**
   * 获取本周提交记录
   */
  static async getThisWeekCommits(
    projectPath: string,
    author?: string,
    includeDiff?: boolean
  ): Promise<{ success: boolean; data?: GitCommit[]; error?: string }> {
    const today = new Date();
    const dayOfWeek = today.getDay(); // 0=周日, 1=周一, ..., 6=周六
    
    // 计算本周一的日期
    const mondayOffset = dayOfWeek === 0 ? -6 : 1 - dayOfWeek; // 如果是周日，往前推6天到周一；否则计算到周一的偏移
    const startOfWeek = new Date(today.getTime() + mondayOffset * 24 * 60 * 60 * 1000);
    startOfWeek.setHours(0, 0, 0, 0);
    
    // 计算本周日的日期 - 周报应该包含完整的一周数据（周一到周日）
    const sundayOffset = dayOfWeek === 0 ? 0 : 7 - dayOfWeek;
    const endOfWeek = new Date(today.getTime() + sundayOffset * 24 * 60 * 60 * 1000);
    endOfWeek.setHours(23, 59, 59, 999);
    
    return this.getCommitsByDateRange(
      projectPath,
      startOfWeek.toISOString(),
      endOfWeek.toISOString(),
      author,
      includeDiff
    );
  }

  /**
   * 获取上周提交记录
   */
  static async getLastWeekCommits(
    projectPath: string,
    author?: string
  ): Promise<{ success: boolean; data?: GitCommit[]; error?: string }> {
    const today = new Date();
    const startOfLastWeek = new Date(today);
    startOfLastWeek.setDate(today.getDate() - today.getDay() - 7); // 上周日
    startOfLastWeek.setHours(0, 0, 0, 0);
    
    const endOfLastWeek = new Date(startOfLastWeek);
    endOfLastWeek.setDate(startOfLastWeek.getDate() + 6); // 上周六
    endOfLastWeek.setHours(23, 59, 59, 999);
    
    return this.getCommitsByDateRange(
      projectPath,
      startOfLastWeek.toISOString(),
      endOfLastWeek.toISOString(),
      author
    );
  }

  /**
   * 获取Git仓库信息
   */
  static async getRepoInfo(projectPath: string): Promise<{
    success: boolean;
    data?: { currentBranch: string; remoteUrl: string };
    error?: string;
  }> {
    try {
      const apiResult = await ApiService.git.getRepoInfo(projectPath);
      return {
        success: apiResult.success,
        data: apiResult.data ? {
          currentBranch: apiResult.data.branch,
          remoteUrl: apiResult.data.remoteUrl
        } : undefined,
        error: apiResult.error
      };
    } catch (error) {
      return {
        success: false,
        error: `获取Git仓库信息失败: ${error instanceof Error ? error.message : '未知错误'}`
      };
    }
  }

  /**
   * 格式化提交记录为报告内容
   */
  static formatCommitsForReport(commits: GitCommit[]): string {
    if (!commits || commits.length === 0) {
      return '本期间内没有提交记录。';
    }

    let report = '';
    
    // 按日期分组
    const commitsByDate = commits.reduce((acc, commit) => {
      const safeDate = this.safeCreateDate(commit.date);
      const date = safeDate.toLocaleDateString('zh-CN');
      if (!acc[date]) {
        acc[date] = [];
      }
      acc[date].push(commit);
      return acc;
    }, {} as Record<string, GitCommit[]>);

    // 生成报告内容
    Object.entries(commitsByDate)
      .sort(([a], [b]) => {
        const dateA = this.safeCreateDate(a);
        const dateB = this.safeCreateDate(b);
        return dateB.getTime() - dateA.getTime();
      })
      .forEach(([date, dayCommits]) => {
        report += `\n## ${date}\n\n`;
        
        dayCommits.forEach(commit => {
          report += `### ${commit.message || 'N/A'}\n`;
          report += `- **提交者**: ${commit.author || 'N/A'}\n`;
          report += `- **提交时间**: ${this.safeCreateDate(commit.date).toLocaleString('zh-CN')}\n`;
          report += `- **提交哈希**: ${commit.hash ? commit.hash.substring(0, 8) : 'N/A'}\n`;
          
          if (commit.files && commit.files.length > 0) {
            report += `- **变更文件**: ${commit.files.length}个\n`;
            const totalAdditions = commit.files.reduce((sum, file) => sum + file.additions, 0);
            const totalDeletions = commit.files.reduce((sum, file) => sum + file.deletions, 0);
            report += `- **代码变更**: +${totalAdditions} -${totalDeletions}\n`;
            
            // 列出主要变更文件
            const mainFiles = commit.files.slice(0, 5); // 只显示前5个文件
            report += `- **主要文件**:\n`;
            mainFiles.forEach(file => {
              report += `  - ${file.file} (${file.type}, +${file.additions} -${file.deletions})\n`;
            });
            
            if (commit.files.length > 5) {
              report += `  - 还有 ${commit.files.length - 5} 个文件...\n`;
            }
          }
          
          report += '\n';
        });
      });

    return report;
  }

  /**
   * 获取提交统计信息
   */
  static getCommitStats(commits: GitCommit[]): {
    totalCommits: number;
    totalFiles: number;
    totalAdditions: number;
    totalDeletions: number;
    authors: string[];
    dateRange: { start: string; end: string } | null;
  } {
    if (!commits || commits.length === 0) {
      return {
        totalCommits: 0,
        totalFiles: 0,
        totalAdditions: 0,
        totalDeletions: 0,
        authors: [],
        dateRange: null
      };
    }

    const authors = [...new Set(commits.map(c => c.author))];
    const dates = commits
      .map(c => this.safeCreateDate(c.date))
      .filter(date => this.isValidDate(date))
      .sort((a, b) => a.getTime() - b.getTime());
    
    let totalFiles = 0;
    let totalAdditions = 0;
    let totalDeletions = 0;
    
    commits.forEach(commit => {
      if (commit.files) {
        totalFiles += commit.files.length;
        totalAdditions += commit.files.reduce((sum, file) => sum + file.additions, 0);
        totalDeletions += commit.files.reduce((sum, file) => sum + file.deletions, 0);
      }
    });

    return {
      totalCommits: commits.length,
      totalFiles,
      totalAdditions,
      totalDeletions,
      authors,
      dateRange: dates.length > 0 ? {
        start: dates[0].toISOString(),
        end: dates[dates.length - 1].toISOString()
      } : null
    };
  }
}